"""Jinja support package.

This provides code to integrate Django with Jinja.
"""

from __future__ import absolute_import

from itertools import chain
from django.conf import settings
from django.http import HttpResponse
from django.core.exceptions import ImproperlyConfigured
from django.template.context import get_standard_processors
from django.template import TemplateDoesNotExist
from jinja2 import Environment, FileSystemLoader, TemplateNotFound
from jinja2.defaults import DEFAULT_NAMESPACE


# the environment is unconfigured until the first template is loaded.
_jinja_env = None

_globals = {}

def jinja_global(func, name=None):
    if name:
        _globals[name] = func
    else:
        _globals[func.__name__] = func

def get_env():
    """Get the Jinja2 env and initialize it if necessary."""
    global _jinja_env
    if _jinja_env is None:
        _jinja_env = create_env()
    return _jinja_env


def create_env():
    """Create a new Jinja2 environment."""
    # XXX: Hack
    # Django needs to initialize the template loaders at least once for the
    # debug HTML template to load.
    from django.template import  loader
    try:
        loader.get_template('DOES_NOT_EXIST')
    except TemplateDoesNotExist:
        pass

    searchpath = list(settings.JINJA2_TEMPLATE_DIRS)
    options = getattr(settings, 'JINJA2_ENVIRONMENT_OPTIONS', {})
    return Environment(loader=FileSystemLoader(searchpath),
                       **options)

def get_template(template_name, globals=None):
    """Load a template."""
    try:
        return get_env().get_template(template_name, globals=globals)
    except TemplateNotFound, e:
        raise TemplateDoesNotExist(str(e))


def select_template(templates, globals=None):
    """Try to load one of the given templates."""
    env = get_env()
    for template in templates:
        try:
            return env.get_template(template, globals=globals)
        except TemplateNotFound:
            continue
    raise TemplateDoesNotExist(', '.join(templates))


def render_to_string(template_name, context=None, request=None,
                     processors=None):
    """Render a template into a string."""
    context = dict(context or {})
    context.update(_globals)
    if request is not None:
        context['request'] = request
        for processor in chain(get_standard_processors(), processors or ()):
            context.update(processor(request))
    return get_template(template_name).render(context)


def render_to_response(template_name, context=None, request=None,
                       processors=None, mimetype=None):
    """Render a template into a response object."""
    return HttpResponse(render_to_string(template_name, context, request,
                                         processors), mimetype=mimetype)

# XXX: Temp hack.
import hcp.jinja.extra
